function getBuffRemianTime(unit, buff)
	local n,_,icon,count,_,dur,x,_,_= UnitBuff(unit, buff)
	if n then
		return math.max(0, x - GetTime())  , count
	end
	return 0, 0
end



function getDebuffRemainTime( unit, debuff )
	-- body
	local n,_,icon,_,_,dur,x,unitCaster,_=UnitDebuff(unit, debuff);
	if n and unitCaster == 'player' then
		return math.max(0, x  - GetTime())
	end

	return 0
end

function getHpParent( unit  )
	-- body
	return UnitHealth(unit)/UnitHealthMax(unit)
end

function getCD(spell)
	-- body
	-- print('getCD', spell)
	local start, duration, enabled = GetSpellCooldown(spell)
	if start == nil then
		print('getcd is nil', spell)
		return 100
	end

	if enabled == 0 then
		return duration
	elseif ( start > 0 and duration > 0) then
		return start + duration - GetTime()
	else
		return 0
	end
end

local _lastTime = 0
local function onUpdate()
	if UnitIsDeadOrGhost("player") then
		return
	end

	local now = GetTime()
	if now - _lastTime < 0.1 then
		return
	end

	_lastTime = now

	-- ut.onUpdate()
end
F:SetScript("OnUpdate",onUpdate)

function haveStealableBuff( )
    return foreachBuff('target', function(name, debuffType)
        return debuffType == 'Magic'
    end)
end

function foreachDebuff(unit, callback)
	for i = 1, 40 do
		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster,
		isStealable, shouldConsolidate, spellId
		= UnitDebuff(unit, i)
		if not name then
			return false
		end

		if callback(name, debuffType) then
			return true
		end
	end
	return false
end

function foreachBuff(unit, callback)
	for i = 1, 40 do
		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable,
		shouldConsolidate, spellId=UnitBuff(unit,i);
		if not name then
			return false
		end

		if callback(name, debuffType) then
			return true
		end
	end
	return false
end


function array_find(arr, pred)
	for i,v in ipairs(arr) do
		if pred(v) then
			return v
		end
	end
end

local immune_all_buff = {"剑刃风暴", "圣盾术", "冰箱", "冰封之韧", "威慑", "邪恶之地"};
function immune_all( target )
	for _, buff in ipairs(immune_all_buff) do
		if UnitBuff(target, buff) then
			return true;
		end
	end

	return false
end

local immune_slowdown_buff = {"剑刃风暴", "自由之手", "主人的召唤", "威慑"};
function immune_slowdown( target )
	for _, buff in ipairs(immune_slowdown_buff) do
		if UnitBuff(target, buff) then
			return true;
		end
	end

	return false
end

local immune_coma_buff = {"剑刃风暴", "圣盾术", "冰箱", "冰封之韧", "威慑", "邪恶之地"};
function immune_coma(target)
	for _, buff in ipairs(immune_coma_buff) do
		if UnitBuff(target, buff) then
			return true;
		end
	end

	return false
end
function buffExist( unit, ... )
	-- body
	for _, buff in ipairs({...}) do
		if  UnitBuff(unit, buff) then
			return true
		end
	end
	return false
end

function PVPOther()
	for i=1, 3 do
		local t = 'arena' .. i
		if UnitExists(t) and not UnitIsUnit("target", t) then
			return t
		end
	end
end

function GetMidPosition( object1, object2, bili)
	-- body
	local bili = bili or 0.5
	local x1, y1, z1 = ObjectPosition(object1)
	local x2, y2, z2 = ObjectPosition(object2)
	local dx, dy, dz = x2 - x1, y2 - y1, z2 - z1

	return x1 + dx * bili, y1 + dy * bili, z1 + dz * bili

	-- return (x1 + x2) / 2, (y1 + y2) / 2, (z1 + z2) / 2
end

function click(t)
--	print(ObjectPosition(t))
	CastAtPosition(ObjectPosition(t))
end

function interruptJudge(unit)
	
	if not UnitExists(unit) then
		return
	end

	if UnitIsDead(unit) then
		return
	end

	if UnitIsFriend('player',unit) then
		-- return
	end

	local spell, rank, displayName, icon, startTime, endTime, isTradeSkill, castID, interrupt = UnitCastingInfo(unit)

	if spell and not interrupt then
		-- return endTime / 1000 - GetTime() < 0.5
		return true
	end
	local spellName, nameSubtext, text, texture, startTime, endTime, isTradeSkill, interrupt = UnitChannelInfo(unit)
	if spellName and not interrupt then
		-- return GetTime() - startTime / 1000 > 0.1
		return true
	end

end

function daduan(name)
     s.sf(function()
        local usable, nomana = IsUsableSpell(name)
        local start, duration, enabled = GetSpellCooldown(name)
        -- print(usable, start)
        if not usable or start ~= 0 then
            return false
        end

        if interruptJudge('target') then
            ut.cast(name, 'target')
            return true
        end

        for i=1, 5 do
            local t = 'arena' .. i
            if UnitExists(t) then
                if interruptJudge(t) then
                    ut.cast(name,t)
                    return true
                end
            else 
                break
            end
        end
    end)
end
